#include "GameScene.h"
#include "cocos2d.h"
#include "Ball.h"
#include "Block.h"
#include "MapCreator.h"
#include "MenuScene.h"
#include "Reward.h"
USING_NS_CC;

Scene* GameScene::createScene(){
	auto scene = Scene::create();
	auto layer = GameScene::create();
	scene->addChild(layer);
	return scene;
}

bool GameScene::init(){
	if (!Layer::init())
	{
		return false;
	}
	
	visibleSize = Director::getInstance()->getVisibleSize();

//	bg_down = Sprite::create("bg1.png");
//	bg_down->setAnchorPoint(Vec2(0.5,0));
//	bg_down->setPosition(Vec2(visibleSize.width/2,0));
//	bg_down->setColor(ccc3(120, 120, 120));
//	this->addChild(bg_down,10);
//
//	bg_up = Sprite::create("bg2.png");
//	bg_up->setAnchorPoint(Vec2(0.5, 0));
//	bg_up->setPosition(Vec2(visibleSize.width /2 ,visibleSize.height));
//	this->addChild(bg_up, 10);

    bg=Node::create();
    bg->setPosition(Vec2::ZERO);
    addChild(bg);
 	
    offsetY = visibleSize.height*.4;
    
	ball = Ball::create();
	ball->setPosition(visibleSize.width / 2, offsetY);
	bg->addChild(ball,10);
	
	EventListenerTouchOneByOne* touchlistener = EventListenerTouchOneByOne::create();
	touchlistener->setSwallowTouches(true);
	touchlistener->onTouchBegan = CC_CALLBACK_2(GameScene::onTouchBegain, this);
	touchlistener->onTouchMoved = CC_CALLBACK_2(GameScene::onTouchMoved, this);
	EventDispatcher* eventDispatcher = Director::getInstance()->getEventDispatcher();
	eventDispatcher->addEventListenerWithSceneGraphPriority(touchlistener, this);
	

	this->scheduleUpdate();
    
    MapCreator *mc=MapCreator::createWithGameScene(this);
    addChild(mc);
    
    scoreLabel = Label::createWithTTF("0", "fonts/Marker Felt.ttf", 80);
    scoreLabel->setPosition(900.0f,1820.0f);
    addChild(scoreLabel,1);
	scoreLabel->setVisible(false);
    
	return true;
}

void GameScene::update(float dt){
    runAndhitUpdate(dt);
    removeUpdate(dt);
    rewardUpdate(dt);
}

void GameScene::runAndhitUpdate(float dt){
    float lastY=ball->getPositionY();
    ball->setPositionY(lastY+speed*dt);
    bg->setPositionY(offsetY-ball->getPositionY());
    
    for (const auto& child : bg->getChildren()){
        if (child->getName()=="Block"){
            Block *b=dynamic_cast<Block*>(child);
            if (ball->getPositionX() > b->getPositionX()-b->getBlockWidth()/2 &&
                ball->getPositionX() < b->getPositionX()+b->getBlockWidth()/2 &&
                lastY < b->getPositionY()-b->getBlockWidth()/2-ball->getBlockWidth()/2 &&
                ball->getPositionY() > b->getPositionY()-b->getBlockWidth()/2-ball->getBlockWidth()/2) {
                b->hit();
                ball->hit();
                
                if (ball->count<0) {
                    unscheduleUpdate();
                    //////
                    isOver=true;
					auto end_bgup = Sprite::create("block.png");
					end_bgup->setScale(2.0f);
					end_bgup->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 10 * 7));
					this->addChild(end_bgup, 20);
					auto label_score = Label::createWithTTF("0", "fonts/Marker Felt.ttf", 90);
					__String *label_scoreStr = __String::createWithFormat("%d", score);
					label_score->setString(label_scoreStr->getCString());
					label_score->setTextColor(Color4B::BLACK);
					label_score->setPosition(Vec2(end_bgup->getContentSize().width / 2, end_bgup->getContentSize().height / 3 * 2));
					end_bgup->addChild(label_score);

					auto sprite_crown = Sprite::create("crown.png");
					sprite_crown->setScale(0.4);
					sprite_crown->setPosition(Vec2(end_bgup->getContentSize().width / 3, end_bgup->getContentSize().height / 3));
					end_bgup->addChild(sprite_crown);

					auto label_record = Label::createWithTTF("30", "fonts/Marker Felt.ttf", 90);
					label_record->setScale(0.5);
					label_record->setTextColor(Color4B::BLACK);
					label_record->setPosition(Vec2(end_bgup->getContentSize().width / 3 * 2, end_bgup->getContentSize().height / 3));
					end_bgup->addChild(label_record);

					int socre_record = UserDefault::getInstance()->getIntegerForKey("SCORE");
					__String *recordStr = __String::createWithFormat("%d", socre_record);
					label_record->setString(recordStr->getCString());
					scoreLabel->setVisible(false);
					if (score > socre_record)
					{
						UserDefault::getInstance()->setIntegerForKey("SCORE", score);
						UserDefault::getInstance()->flush();
					}

                }else{
					scoreLabel->setVisible(true);
                    __String *scoreStr=__String::createWithFormat("%d",++score);
                    scoreLabel->setString(scoreStr->getCString());
                }
            }
        }
    }
}

void GameScene::removeUpdate(float dt){
//     for (const auto& child : bg->getChildren()){
//         if ((child->getName()=="Block" || child->getName()=="Reward") && child->getPositionY()<ball->getPositionY()-offsetY-300) {
//             child->removeFromParent();
//         }
//     }
}

void GameScene::rewardUpdate(float dt){
    for (const auto& child : bg->getChildren()){
        if (child->getName()=="Reward") {
            Reward *reward=dynamic_cast<Reward*>(child);
            if(ball->getPosition().distance(reward->getPosition())<reward->getRewardWidth()/2+ball->getBlockWidth()/2){
                ball->addBalls(reward->count);
				reward->hit();
            }
        }
    }
}

bool GameScene::onTouchBegain(Touch* touch, Event* event){
    lastTouchX = touch->getLocation().x;
    if (isOver) {
        Director::getInstance()->replaceScene(MenuScene::createScene());
    }
    return true;
}
void GameScene::onTouchMoved(Touch* touch, Event* event){
	float x = touch->getLocation().x;
	try2MoveX(x - lastTouchX);
	lastTouchX = touch->getLocation().x;
}

void GameScene::try2MoveX(float detaX){
    float lastX = ball->getPositionX();
	float x = lastX + detaX;
	if (x<ball->getBlockWidth()/2){
		x = ball->getBlockWidth()/2;
	}
	if (x>1080-ball->getBlockWidth()/2){
		x = 1080.0f-ball->getBlockWidth()/2;
	}
    
    for (const auto& child : bg->getChildren()){
        if (child->getName()=="Block"){
            Block *b=dynamic_cast<Block*>(child);
            if (ball->getPositionY() > b->getPositionY()-b->getBlockWidth()/2 &&
                ball->getPositionY() < b->getPositionY()+b->getBlockWidth()/2 &&
                lastX <= b->getPositionX()-b->getBlockWidth()/2-ball->getBlockWidth()/2 &&
                x > b->getPositionX()-b->getBlockWidth()/2-ball->getBlockWidth()/2) {
                x=b->getPositionX()-b->getBlockWidth()/2-ball->getBlockWidth()/2;
            }
            if (ball->getPositionY() > b->getPositionY()-b->getBlockWidth()/2 &&
                ball->getPositionY() < b->getPositionY()+b->getBlockWidth()/2 &&
                lastX >= b->getPositionX()+b->getBlockWidth()/2+ball->getBlockWidth()/2 &&
                x < b->getPositionX()+b->getBlockWidth()/2+ball->getBlockWidth()/2) {
                x=b->getPositionX()+b->getBlockWidth()/2+ball->getBlockWidth()/2;
            }
        }
    }
	ball->setPositionX(x);
}

